#region Copyright (c) 2000-2011 Developer Express Inc.
/*
{*******************************************************************}
{                                                                   }
{       Developer Express .NET Component Library                    }
{                                                                   }
{                                                                   }
{       Copyright (c) 2000-2011 Developer Express Inc.              }
{       ALL RIGHTS RESERVED                                         }
{                                                                   }
{   The entire contents of this file is protected by U.S. and       }
{   International Copyright Laws. Unauthorized reproduction,        }
{   reverse-engineering, and distribution of all or any portion of  }
{   the code contained in this file is strictly prohibited and may  }
{   result in severe civil and criminal penalties and will be       }
{   prosecuted to the maximum extent possible under the law.        }
{                                                                   }
{   RESTRICTIONS                                                    }
{                                                                   }
{   THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES           }
{   ARE CONFIDENTIAL AND PROPRIETARY TRADE                          }
{   SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS   }
{   LICENSED TO DISTRIBUTE THE PRODUCT AND ALL ACCOMPANYING .NET    }
{   CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY.                 }
{                                                                   }
{   THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED      }
{   FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE        }
{   COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE       }
{   AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT  }
{   AND PERMISSION FROM DEVELOPER EXPRESS INC.                      }
{                                                                   }
{   CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON       }
{   ADDITIONAL RESTRICTIONS.                                        }
{                                                                   }
{*******************************************************************}
*/
#endregion Copyright (c) 2000-2010 Developer Express Inc.

namespace DevExpress.OAuth.Web.Authentication {
    using System;
    using System.Web;
    using System.Web.Security;
    using DevExpress.OAuth.Authentication;
    using DevExpress.OAuth.Provider;

    public static class MixedAuthentication {
        public static MixedAuthenticationPrincipal GetMixedPrincipal() {
            HttpContext context = HttpContext.Current;
            if (context != null) {
                MixedAuthenticationPrincipal principal = context.User as MixedAuthenticationPrincipal;
                if (principal != null
                                && principal.Identity is MixedAuthenticationIdentity) {

                    return principal;
                }
            }
            MixedAuthenticationIdentity identity = GetMixedIdentity();
            if (identity == null) {
                return null;
            }
            return new MixedAuthenticationPrincipal(identity);
        }

        public static MixedAuthenticationIdentity GetMixedIdentity() {
            HttpContext context = HttpContext.Current; 
            if (context == null) { 
                return null;
            }
            if (context.User != null) {
                MixedAuthenticationIdentity mixedIdentity
                            = context.User.Identity as MixedAuthenticationIdentity;
                if (mixedIdentity != null) {
                    return mixedIdentity;
                }
            }

            MixedAuthenticationTicket ticket;
            string authorizationHeader = HttpContext.Current != null ? 
                    HttpContext.Current.Request.Headers["Authorization"] : null;
            if (!String.IsNullOrEmpty(authorizationHeader)) {
                
                ValidationScope scope;                
                TokenIdentity tokenIdentity = ServiceProvider.GetTokenIdentity(
                                context.Request.HttpMethod,
                                context.Request.Url, 
                                authorizationHeader,
                                out scope);
                if (tokenIdentity == null) {
                    if (scope != null) {
                        foreach (ValidationError error in scope.Errors) {
                            throw new HttpException(error.StatusCode, error.Message);
                        }
                    }
                    return null;
                }
                ticket = MixedAuthenticationTicket.FromJson(tokenIdentity.AuthenticationTicket);

            } else {
                FormsIdentity formsIdentity = null;

                if (context.User != null) {
                    formsIdentity
                                = context.User.Identity as FormsIdentity;
                }

                FormsAuthenticationTicket formsTicket = null;
                if (formsIdentity
                                    != null) {
                    formsTicket = formsIdentity.Ticket;
                }

                if (formsTicket == null) {
                    /* Let FormsAuthentication do all the work (Extract/Renew the cookie...)
                     * So if we get here it means FormsAuthenticationModule was not configured or 
                     * we are really not authenticated. */
                    return null;
                }

                ticket = MixedAuthenticationTicket.FromJson(formsTicket.UserData);
            }
            
            return  new MixedAuthenticationIdentity(
                                ticket.Identity,
                                ticket.Email,
                                ticket.Principal,
                                ticket.AuthenticationType,
                                ticket.FullName,
                                ticket.PictureUrl);
        }

        public static HttpCookie GetAuthCookie(
            MixedAuthenticationTicket mixed,
            bool createPersistentCookie,
            string strCookiePath) {

            string userName = mixed.Identity;
            if (userName == null) { userName = String.Empty; }

            if ((strCookiePath == null) || (strCookiePath.Length < 1)) {
                strCookiePath = FormsAuthentication.FormsCookiePath;
            }
            FormsAuthenticationTicket ticket
                = new FormsAuthenticationTicket(2, userName,
                    DateTime.Now, DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes), createPersistentCookie,
                    mixed.ToJson(), strCookiePath);

            string str = FormsAuthentication.Encrypt(ticket);
            if ((str == null) || (str.Length < 1)) {
                throw new HttpException();
            }
            HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, str) {
                HttpOnly = true,
                Path = strCookiePath,
                Secure = FormsAuthentication.RequireSSL,
            };
            if (FormsAuthentication.CookieDomain != null) {
                cookie.Domain = FormsAuthentication.CookieDomain;
            }
            if (ticket.IsPersistent) {
                cookie.Expires = ticket.Expiration;
            }
            return cookie;
        }

        public static void SetAuthCookie(MixedAuthenticationTicket mixed,
            bool createPersistentCookie,
            string strCookiePath) {

            HttpCookie cookie = GetAuthCookie(mixed, createPersistentCookie, strCookiePath);
            if (cookie != null) {
                System.Web.HttpContext.Current.Response.Cookies.Set(cookie);
            }
        }
    }
}